<!--
 * @Author: 小花
 * @Date: 2022-04-07 14:29:14
 * @LastEditors: 小花
 * @LastEditTime: 2022-06-14 11:44:46
 * @FilePath: /adminClient/src/views/Login/LoginView.vue
 * @Description:登录
-->
<template>
  <div class="LoginPage">
    <!-- 背景 -->
    <div id="login-bg" class="container-fluid">
      <div class="bg-img"></div>
      <div class="bg-color"></div>
      <!-- 装饰元素 -->
      <div class="decoration decoration-1"></div>
      <div class="decoration decoration-2"></div>
      <div class="decoration decoration-3"></div>
    </div>
    <!-- 背景结束 -->
    <div class="container" id="login">
      <div class="row justify-content-center">
        <div class="col-lg-8">
          <div class="login">
            <h1>后勤报修系统</h1>
            <h2>管理员登录</h2>
            <!-- 登录表单 -->
            <form>
              <div class="form-group">
                <label for="exampleInputEmail1">账号</label>
                <input type="text" v-model="loginInfo.account" class="form-control" id="exampleInputEmail1"
                  aria-describedby="emailHelp" placeholder="请输入管理员账号">
              </div>
              <div class="form-group">
                <label for="exampleInputPassword1">密码</label>
                <input type="password" v-model="loginInfo.password" class="form-control" id="exampleInputPassword1"
                  placeholder="请输入密码">
              </div>
              <br>
              <button type="button" @click="submit" class="btn btn-lg btn-block btn-success">
                登 录
              </button>
            </form>
            <!-- 登录表单结束 -->
            <div class="system-info">
              <p>后勤报修管理系统 v1.0</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

</template>

<script lang="ts">
import { defineComponent, reactive, toRefs } from 'vue'

import { useStore } from '@/plugins/store/store'
import { responseEnum, responseUtil } from '@/plugins/request/responseUtil'
import { pubKeyEncrypt, verify } from '@/plugins/encrypt/rsa'
import router from '@/plugins/router/router'
import { PullKey, LoginStart, verifyLoginOverdue } from '@/plugins/request/http'

import { ElMessage } from 'element-plus'
import { ISignData } from '@/model/Login/support/SignInfo'
import LoginViewData from '@/model/Login/LoginView'
import nProgress from 'nprogress'
import _cloneDeep from 'lodash/cloneDeep'
import { AxiosResponse } from 'axios'

export default defineComponent({
  name: 'LoginView',
  setup () {
    const store = useStore()
    const coreData = reactive(new LoginViewData())

    const submit = async () => {
      if (!coreData.loginInfo.account || !coreData.loginInfo.password) {
        ElMessage.warning('账号和密码不能为空！')
        return
      }

      nProgress.start()
      const verifyResult = await checkLoginState()
      if (verifyResult) {
        router.replace({ path: '/MainView' })
        nProgress.done()
        return
      }
      if (!store.publicKey) store.publicKey = await getKey()
      const copyData = _cloneDeep(coreData.loginInfo)
      await import('ts-md5/dist/md5').then(module => {
        copyData.account = module.Md5.hashStr(coreData.loginInfo.account)
        copyData.password = module.Md5.hashStr(coreData.loginInfo.password)
      })

      const enCopyData = pubKeyEncrypt(store.publicKey, JSON.stringify(copyData))
      if (!enCopyData) { nProgress.done(); throw new Error('数据加密出现错误') }
      LoginStart(enCopyData).then(res => {
        if (res.data.code !== responseEnum.LOGIN_SUCCESS) {
          ElMessage.error(res.data.msg || '登录失败，请检查账号密码')
          nProgress.done()
          return
        }
        store.userData = res.data.data
        ElMessage.success(res.data.msg || '登录成功')
        router.replace({ path: '/MainView' })
        nProgress.done()
      }).catch(() => { 
        ElMessage.error('网络错误，请稍后再试')
        nProgress.done() 
      })
    }

    /**
     * @description: 重复登录检测
     * @param {*} Promise
     * @return {*}
     */
    const checkLoginState = async (): Promise<boolean> => {
      if (store.userData && Object.keys(store.userData).length) {
        const result: responseUtil = await (await verifyLoginOverdue()).data
        if (result.code === responseEnum.LOGIN_VALID) {
          return true
        }
      }
      return false
    }

    /**
     * @description: 获取密钥
     * @param {*} Promise
     * @return {*}
     */
    const getKey = (): Promise<string> => {
      return new Promise((resolve, reject) => {
        PullKey().then((res: AxiosResponse<responseUtil>) => {
          if (res.data.code !== responseEnum.OK) {
            ElMessage.error(res.data.msg || '获取密钥失败')
            reject(res.data.msg)
          } else {
            const map: ISignData = res.data.data
            if (!verify(map.publicKey, map.strAbs, map.strAbsSign)) reject(new Error('数字签名认证失败，请刷新页面重试'))
            store.publicKey = map.publicKey
            console.log('签名认证成功')
            resolve(map.publicKey)
          }
        })
      })
    }
    getKey()

    return {
      ...toRefs(coreData),
      submit
    }
  }
})
</script>

<style lang='scss' scoped>
@import url(https://fonts.googleapis.com/css?family=Montserrat);
@import url('@/assets/css/bootstrap.min.css');

.LoginPage {
  font-family: 'Montserrat', "Microsoft YaHei", "微软雅黑", sans-serif;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  height: 100vh;
  overflow: hidden;
}

#login-bg.container-fluid {
  padding: 0;
  height: 100%;
  position: absolute;
  width: 100%;
}

/* 背景图和颜色层 */
.bg-img,
.bg-color {
  width: 100%;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
  overflow: hidden;
}

.bg-color {
  background: linear-gradient(135deg, rgba(124, 189, 142, 0.9) 0%, rgba(76, 162, 205, 0.85) 100%);
  z-index: 1;
}

.bg-img {
  background-image: url('https://images.unsplash.com/photo-1598902108854-10e335adac99?q=80&w=2000');
  background-size: cover;
  background-position: center;
  filter: blur(3px);
  z-index: 0;
}

/* 装饰元素 */
.decoration {
  position: absolute;
  border-radius: 50%;
  z-index: 1;
}

.decoration-1 {
  width: 300px;
  height: 300px;
  background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 70%);
  top: 10%;
  right: 15%;
  animation: float 8s infinite ease-in-out;
}

.decoration-2 {
  width: 200px;
  height: 200px;
  background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 70%);
  bottom: 15%;
  left: 10%;
  animation: float 6s infinite ease-in-out reverse;
}

.decoration-3 {
  width: 150px;
  height: 150px;
  background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 70%);
  top: 20%;
  left: 20%;
  animation: float 10s infinite ease-in-out;
}

@keyframes float {
  0% { transform: translateY(0) rotate(0deg); }
  50% { transform: translateY(-20px) rotate(5deg); }
  100% { transform: translateY(0) rotate(0deg); }
}

#login {
  position: relative;
  z-index: 2;
  padding-top: 5%;
  text-align: center;
}

.login {
  width: 100%;
  max-width: 450px;
  margin: 0 auto;
  background-color: rgba(255, 255, 255, 0.95);
  padding: 40px;
  border-radius: 15px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
  transition: all 0.3s ease;
}

.login:hover {
  transform: translateY(-5px);
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
}

.login h1 {
  margin-top: 10px;
  font-weight: bold;
  font-size: 32px;
  letter-spacing: 1px;
  color: #2c3e50;
}

.login h2 {
  font-size: 18px;
  color: #7f8c8d;
  margin-bottom: 30px;
  font-weight: normal;
}

.login form {
  max-width: 100%;
  margin: 30px auto;
}

.form-group {
  text-align: left;
  margin-bottom: 25px;
}

.form-group label {
  display: block;
  margin-bottom: 8px;
  font-weight: 500;
  color: #34495e;
  font-size: 16px;
}

.login .btn {
  border-radius: 8px;
  text-transform: uppercase;
  font-weight: bold;
  letter-spacing: 2px;
  font-size: 18px;
  padding: 12px;
  background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
  border: none;
  margin-top: 15px;
  transition: all 0.3s ease;
}

.login .btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(46, 204, 113, 0.3);
}

.login .btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 5px rgba(46, 204, 113, 0.3);
}

.form-group input {
  font-size: 16px;
  border: none;
  background-color: #f5f7fa;
  color: #2c3e50 !important;
  padding: 15px 20px;
  border-radius: 8px;
  transition: all 0.3s ease;
  width: 100%;
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.05);
}

.form-group input:focus {
  background-color: #fff;
  box-shadow: 0 0 0 3px rgba(46, 204, 113, 0.2);
  outline: none;
}

.system-info {
  margin-top: 30px;
  color: #95a5a6;
  font-size: 12px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .login {
    padding: 30px 20px;
    margin: 0 20px;
  }

  .login h1 {
    font-size: 28px;
  }

  .form-group input {
    padding: 12px 15px;
  }

  #login {
    padding-top: 10%;
  }
}
</style>
